import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
//碰撞
import { Octree } from 'three/examples/jsm/math/Octree.js'
import { Capsule } from 'three/examples/jsm/math/Capsule.js'
// import * as dat from 'dat.gui';
export const mixins = {
  data() {
    return {
   cameras:null
        };
  },

  created() {},
    mounted() { },
    beforeDestroy() {
  
    clearTimeout()
    try {
      this.scene.clear()
      this.render.dispose()
      this.render.forceContextLoss()
      this.render.content = null
      // cancelAnimationFrame(animationID) // 去除animationFrame
      const gl = this.render.domElement.getContext('webgl')
      gl && gl.getExtension('WEBGL_lose_context').loseContext()
    } catch (e) {
      console.log(e)
    }
    },
      computed: {
    getPosition() {
      //根据返回的位置信息计算物品提示小标位
      let maincontWidth = this.$el.offsetWidth
      let maincontHeight = this.$el.offsetHeight
      let leftPercentage = ((this.tipPosition.x + 25) / maincontWidth) * 100
      let topPercentage = ((this.tipPosition.y - 30) / maincontHeight) * 100
      return 'left:' + leftPercentage + '%;top:' + topPercentage + '%;'
    }
  },
    methods: {
            //初始化
    init() {
   
      this.initSence()
      
      this.raycaster = new THREE.Raycaster() // 设置光线拾取
      this.clock = new THREE.Clock()
      this.mouse = new THREE.Vector2()
        },
            //初始化相机
    initCeremar() {
      const camera = new THREE.PerspectiveCamera(
        50,
        window.innerWidth / window.innerHeight,
        0.01,
        10000
      )
      camera.position.set(
        this.cameraOriginal[0],
        this.cameraOriginal[1],
        this.cameraOriginal[2]
      )

      this.camera = camera;
      this.scene.add(this.camera);
      this.cameras=this.camera 
    },
    //初始化场景
    initSence() {
      this.scene = new THREE.Scene()
       this.initLight()
      this.initCeremar()
      this.initRenderer()
       this.initMass()
      this.initCotronl()
      this.initPoint()
     
      this.initFile()
      this.initFileSs(6)
      // this.initFileS(0)
     
    },
    //初始化渲染器
    initRenderer() {
    //   this.render = new THREE.WebGLRenderer({
    //     antialias: true,
    //     logarithmicDepthBuffer: true
    //   })
    //   this.render.setClearColor(0xaaaaaa);
    //   this.render.setPixelRatio(window.devicePixelRatio)
    //    this.render.setSize(window.innerWidth, window.innerHeight)
    //   this.render.shadowMap.enabled = true
    //   this.render.shadowMap.type = THREE.PCFShadowMap;
    //   // this.render.toneMapping = THREE.ACESFilmicToneMapping;
    //   // this.render.toneMappingExposure = 1.2
    //   // this.render.outputColorSpace = THREE.SRGBColorSpace
    //   this.render.outputEncoding = THREE.sRGBEncoding
      

    //    this.$el.appendChild(this.render.domElement)
      // window.addEventListener('resize', this.onWindowResize) //监听窗口变化
        this.render = new THREE.WebGLRenderer({
        antialias: true,
       
        // logarithmicDepthBuffer: true
      })
      this.render.setClearColor(0xaaaaaa);
      // this.render.setPixelRatio(window.devicePixelRatio*2)
       this.render.setSize(window.innerWidth, window.innerHeight)
      this.render.shadowMap.enabled = true
      this.render.shadowMap.type = THREE.PCFSoftShadowMap;
      
      this.render.toneMapping = THREE.ACESFilmicToneMapping;
        this.render.toneMappingExposure = 1
      // this.render.outputEncoding = THREE.LinearSRGBColorSpace
  
      this.render.outputColorSpace = THREE.SRGBColorSpace
      
       this.$el.appendChild(this.render.domElement)
    window.addEventListener('resize', this.onWindowResize) //监听窗口变化
    
      },
        //根据屏幕尺寸变化自适应
        onWindowResize() {
      //浏览器窗口大小改变后重新计算
      this.maincontWidth = this.$el.offsetWidth
      this.maincontHeight = this.$el.offsetHeight
      this.maincontSc = this.maincontWidth / this.maincontHeight
      this.camera.aspect = this.maincontSc
      this.camera.updateProjectionMatrix()
      this.render.setSize(this.maincontWidth, this.maincontHeight)
    }, //鼠标移动6+射线拾取
    //初始化控制器
    initCotronl() {
  

      this.mouse = new THREE.Vector2() //获取鼠标 位置二维坐标信息
      document.body.addEventListener('mousemove', this.onDocumentMouseMove)
      document.body.addEventListener('mousedown', this.onDocumentMouseDown)
      this.$el.addEventListener('mouseup', this.onDocumentMouseUp)
     

    }, //初始化物体
      initFile() {
      this.$emit('loadingfn', true);
      let gltfloader = new GLTFLoader()
      this.app = gltfloader
      const dracoLoader = new DRACOLoader()
      // dracoLoader.setDecoderPath('/draco/')
      dracoLoader.setDecoderPath(
     window.config.VUE_GLB_Base_load
      )
      dracoLoader.preload()
      gltfloader.setDRACOLoader(dracoLoader)
      gltfloader.load(window.config.VUE_GLB_Base + 'CTshi.glb', (gltf) => {
        this.model = gltf.scene
      this.objectReItem = gltf.scene
        gltf.scene.position.set(0, 0, 0)
        if (this.worldOctree) {
          this.worldOctree.fromGraphNode(this.objectReItem)
        }
        gltf.scene.traverse((child) => {
          if (child.isMesh) {
            child.receiveShadow = true
            child.castShadow = true
            child.material.emissiveMap = child.material.map
            if (this.objectNames.includes(child.name)) {
              //将需要检查到的模型放到objects
              this.objects.push(child)
            }
            if (child.name == 'gxspy_zhuozi') {
              child.material.emissive = child.material.color
              child.material.emissiveMap = child.material.map
            }
            //设置模型自发光
            // child.material.emissive = child.material.color
          }
        })
        this.scene.add(gltf.scene)
        this.render.render(this.scene, this.camera)
        this.$emit('loadingfn', false);
        this.animate()
  
        this.initBox();
      
      }
    
      )
        
      },
      destroyOldScene() { 
        if (this.objectFather) {
          this.scene.remove(this.objectFather.scene)
          this.objectFather.scene.traverse((child) => {
            if (child.material) {
              child.material.dispose()
            }
            if (child.geometry) {
              child.geometry.dispose()
            }
            child = null
          })

          this.objectFather = null
        }
      },
      initFileS() {
        console.log('测试步骤');
       },
    //根据步骤渲染物体和动画
      initFileSs(index) {
      
           this.$emit('loadingfn', true);
       
      let gltfloader = new GLTFLoader()
      const dracoLoader = new DRACOLoader()
      // dracoLoader.setDecoderPath('/draco/')
      dracoLoader.setDecoderPath(
      window.config.VUE_GLB_Base_load
      )
      dracoLoader.preload()
      gltfloader.setDRACOLoader(dracoLoader)
      gltfloader.load(window.config.VUE_GLB_Base + this.dhfiles[index].url, (gltf) => {
        this.destroyOldScene()
         
         if (this.worldOctree) {
          this.worldOctree.fromGraphNode(gltf.scene)
        }
        gltf.scene.position.set(0, 0, 0)
        this.objects = []
        console.log(gltf.scene);
        gltf.scene.traverse((child) => {
          if (child.isMesh) {
            child.castShadow = false
            child.receiveShadow = true
            child.castShadow = true
            if (this.objectNames.includes(child.name)) {
              //将需要检查到的模型放到objects
              this.objects.push(child)
            }
          
            child.material.emissiveMap = child.material.map
            // child.material.emissive = child.material.color
          }
          console.log(child.name);
          if (child.name == 'CT9_2') { 
            this.CT9_2 = child
                
          }
          if (child.name == 'CT6_2') { 
            console.log('child',child.visible);
            this.CT6_2 = child       
          }
          if (child.name == 'CT3') { 
            this.CT3 = child
          }
          
        })
        this.scene.add(gltf.scene)
        this.objectFather = gltf
        this.andh = gltf.animations
        console.log('动画数据', gltf.animations)
        this.render.render(this.scene, this.camera)
     
           this.$emit('loadingfn', false);
     
         
        
        // this.initDragControls(this.Farray) //初始化拖拽控制器
      })
        },

        //初始化灯光
      initLight() {
      
        // 仿真
   
      // const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5);
      //   directionalLight1.position.set(5.5, 10, 5);
      // // directionalLight1.castShadow = true;
      // this.scene.add(directionalLight1);
      //   const hemisphereLight = new THREE.HemisphereLight(0xffffff, 1.5);
      //    hemisphereLight.position.set(-19, 2.5, -4);
      // // directionalLight1.castShadow = true;
        // this.scene.add(hemisphereLight);
        // 调整前
      //       const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
      // this.scene.add(ambientLight);
      // const directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.5);
      // // directionalLight1.position.set(0.5, 2, 1);
      //    directionalLight1.position.set(0.5, 2.061, 2.455);
      // // directionalLight1.castShadow = true;
      // this.scene.add(directionalLight1);
      // const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.3);
      // directionalLight2.position.set(-1, 5, -9);
      // directionalLight2.castShadow = false;
      // this.scene.add(directionalLight2);
      // const directionalLight3 = new THREE.DirectionalLight(0xffffff, 0.2);
      // directionalLight3.position.set(-1, 2, -3);
      // directionalLight3.castShadow = true;
      // this.scene.add(directionalLight3);

      // 调整后
    //  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
    //   this.scene.add(ambientLight);
    //   const directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.23);
    //   // directionalLight1.position.set(0.5, 2, 1);
    //      directionalLight1.position.set(0.5, -0.2, 2.4);
    //   // directionalLight1.castShadow = true;
    //   this.scene.add(directionalLight1);
    //   const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.34);
    //   directionalLight2.position.set(-9.2, 8.8, -2);
    //   directionalLight2.castShadow = false;
    //   this.scene.add(directionalLight2);
    //   const directionalLight3 = new THREE.DirectionalLight(0xffffff, 0.17);
    //   directionalLight3.position.set(-2, 2, -10);
    //   directionalLight3.castShadow = true;
        //   this.scene.add(directionalLight3);
        
        //调整2

           const ambientLight = new THREE.AmbientLight(0xffffff, 1);
      this.scene.add(ambientLight);
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.9);
      
         directionalLight1.position.set(3.56, 3.56, -2.2);
      directionalLight1.castShadow = true;
      this.scene.add(directionalLight1);
      const directionalLight2 = new THREE.DirectionalLight(0xffffff,0.6);
      directionalLight2.position.set(-1, -4.8, -1.7);
      directionalLight2.castShadow = false;
      this.scene.add(directionalLight2);
      const directionalLight3 = new THREE.DirectionalLight(0xffffff, 0.87);
      directionalLight3.position.set(1.35, -3.1, -5.7);
      directionalLight3.castShadow = true;
      this.scene.add(directionalLight3);


//       const gui = new dat.GUI();
// // 添加灯光参数
// const lightParams = {
//     ambientLightIntensity: 0.6,
//     directionalLight1Intensity: 0.36,
//     directionalLight2Intensity: 0.34,
//     directionalLight3Intensity: 0.3,
//     directionalLight1PositionX: 0.05,
//     directionalLight1PositionY: -0.65,
//     directionalLight1PositionZ: 2.7,
//     directionalLight2PositionX: -11.2,
//     directionalLight2PositionY: -4.6,
//     directionalLight2PositionZ: -2,
//     directionalLight3PositionX: 0.5,
//     directionalLight3PositionY: 1.6,
//     directionalLight3PositionZ: -3
// };

// // 添加控制器来调整灯光参数
// gui.add(lightParams, 'ambientLightIntensity', 0, 1).onChange(value => {
//     ambientLight.intensity = value;
// });

// gui.add(lightParams, 'directionalLight1Intensity', 0, 1).onChange(value => {
//     directionalLight1.intensity = value;
// });

// gui.add(lightParams, 'directionalLight2Intensity', 0, 1).onChange(value => {
//     directionalLight2.intensity = value;
// });

// gui.add(lightParams, 'directionalLight3Intensity', 0, 1).onChange(value => {
//     directionalLight3.intensity = value;
// });

// // 添加控制器来调整灯光位置
// const directionalLight1Folder = gui.addFolder('Directional Light 1 Position');
// directionalLight1Folder.add(lightParams, 'directionalLight1PositionX', -20, 20).onChange(value => {
//     directionalLight1.position.x = value;
// });
// directionalLight1Folder.add(lightParams, 'directionalLight1PositionY', -20, 20).onChange(value => {
//     directionalLight1.position.y = value;
// });
// directionalLight1Folder.add(lightParams, 'directionalLight1PositionZ', -20, 20).onChange(value => {
//     directionalLight1.position.z = value;
// });

// const directionalLight2Folder = gui.addFolder('Directional Light 2 Position');
// directionalLight2Folder.add(lightParams, 'directionalLight2PositionX', -20, 20).onChange(value => {
//     directionalLight2.position.x = value;
// });
// directionalLight2Folder.add(lightParams, 'directionalLight2PositionY', -20, 20).onChange(value => {
//     directionalLight2.position.y = value;
// });
// directionalLight2Folder.add(lightParams, 'directionalLight2PositionZ', -20, 20).onChange(value => {
//     directionalLight2.position.z = value;
// });

// const directionalLight3Folder = gui.addFolder('Directional Light 3 Position');
// directionalLight3Folder.add(lightParams, 'directionalLight3PositionX', -20, 20).onChange(value => {
//     directionalLight3.position.x = value;
// });
// directionalLight3Folder.add(lightParams, 'directionalLight3PositionY', -20, 20).onChange(value => {
//     directionalLight3.position.y = value;
// });
// directionalLight3Folder.add(lightParams, 'directionalLight3PositionZ', -20, 20).onChange(value => {
//     directionalLight3.position.z = value;
// });

  
    },
    initPoint() {
      //初始换加载箭头指示图标
      const spriteImageLabel = (image) => {
        let textureLoader = new THREE.TextureLoader()
        const imageTexture = textureLoader.load(image)
        return imageTexture
      }
      let imgUrl = require('@/images/pointer.png')
      const spriteMap = spriteImageLabel(imgUrl)
      const spriteMaterial = new THREE.SpriteMaterial({
        map: spriteMap,
        color: 0xffffff
      })
      const sprite = new THREE.Sprite(spriteMaterial)
      sprite.scale.set(0.1, 0.1, 0.1)
      sprite.rotation.set(0, 0, Math.PI * 0.6)
      sprite.visible = false
      this.sprite = sprite
      this.scene.add(sprite)
        },
        //根据按钮播发动画
      playAction(animationName, realName) {
        console.log('播放了动画名称',animationName,'点击的物体',realName);
      this.playIng = true
      const theMixer = new THREE.AnimationMixer(this.objectFather.scene) //动画的物体
      const clip = THREE.AnimationClip.findByName(
        this.objectFather.animations,
        animationName
      ) //要播放的动画名称
      const action = theMixer.clipAction(clip)
      action.loop = THREE.LoopOnce //动画只执行一次
      action.clampWhenFinished = true //播放完成之后自动结束
      action.play()
      this.action = action
      theMixer.addEventListener('finished', () => {
        return setTimeout(() => {
          this.playIng = false
          this.$emit('clickItem', realName)
           console.log('动画播放完成')
        }, 600)
      })
      this.theMixer = theMixer
        },
     //循环渲染
    animate() {
      //镜头移动相关
      const deltaTime = Math.min(0.05, this.clock.getDelta())
      var oldPosition = JSON.parse(JSON.stringify(this.camera.position))
      requestAnimationFrame(this.animate)

      this.changeControls(deltaTime)

      // 开启漫游
      if (this.myshow) { 
         this.updatePlayer(deltaTime)
      }

      this.teleportPlayerIfOob()
      this.render.render(this.scene, this.camera)

      var newPosition = JSON.parse(JSON.stringify(this.camera.position))
      if (this.coverBox && this.areaCheck) {
        if (!this.coverBox.containsPoint(newPosition)) {
          this.camera.position.set(oldPosition.x, oldPosition.y, oldPosition.z)
        }
      }
      if (this.theMixer) {
        //动画渲染  3000 控制动画没一帧之间的时长
        this.theMixer.update(this.clock.getDelta())
        // this.clock.getDelta()
      }
      //清空原本动画事件，回调animate方法
      if (this.outLineAnimationFrameID) {
        window.cancelAnimationFrame(this.outLineAnimationFrameID)
      }
      this.outLineAnimationFrameID = requestAnimationFrame(this.animate)
        },
     // 漫游代码
    initBox() {
      var box = new THREE.Box3();
      box.setFromObject(this.objectReItem);
      this.coverBox = box;
    },
    initMass() {
      this.worldOctree = new Octree()
      this.playerCollider = new Capsule(
        new THREE.Vector3(
          this.cameraOriginal[0],
          this.cameraOriginal[1],
          this.cameraOriginal[2]
        ),
        new THREE.Vector3(
          this.cameraOriginal[0],
          this.cameraOriginal[1] + 1,
          this.cameraOriginal[2]
        ),
        0.35
      )
      this.playerVelocity = new THREE.Vector3()
      this.playerDirection = new THREE.Vector3()
    },
    playerCollisions() {
      const result = this.worldOctree.capsuleIntersect(this.playerCollider)
      this.playerOnFloor = false
      if (result) {
        this.playerOnFloor = result.normal.y > 0
        if (!this.playerOnFloor) {
          this.playerVelocity.addScaledVector(
            result.normal,
            -result.normal.dot(this.playerVelocity)
          )
        }
        this.playerCollider.translate(
          result.normal.multiplyScalar(result.depth)
        )
      }
    },
    updatePlayer(deltaTime) {
      let damping = Math.exp(-4 * deltaTime) - 1
      if (!this.playerOnFloor) {
        this.playerVelocity.y -= this.GRAVITY * deltaTime
        damping *= 0.1
      }
      this.playerVelocity.addScaledVector(this.playerVelocity, damping)
      const deltaPosition = this.playerVelocity
        .clone()
        .multiplyScalar(deltaTime)
      this.playerCollider.translate(deltaPosition)
      this.playerCollisions()
      this.camera.position.copy(this.playerCollider.end)
    },
    getForwardVector() {
      this.camera.getWorldDirection(this.playerDirection)
      this.playerDirection.y = 0
      this.playerDirection.normalize()
      return this.playerDirection
    },
    getSideVector() {
      this.camera.getWorldDirection(this.playerDirection)
      this.playerDirection.y = 0
      this.playerDirection.normalize()
      this.playerDirection.cross(this.camera.up)
      return this.playerDirection
    },
    // wasd位移
    changeControls(deltaTime) {
      const speedDelta = deltaTime * (this.playerOnFloor ? 25 : 8)
      if (this.keyStates['KeyW']) {
        this.playerVelocity.add(
          this.getForwardVector().multiplyScalar(speedDelta)
        )
      }
      if (this.keyStates['KeyS']) {
        this.playerVelocity.add(
          this.getForwardVector().multiplyScalar(-speedDelta)
        )
      }
      if (this.keyStates['KeyA']) {
        this.playerVelocity.add(
          this.getSideVector().multiplyScalar(-speedDelta)
        )
      }
      if (this.keyStates['KeyD']) {
        this.playerVelocity.add(this.getSideVector().multiplyScalar(speedDelta))
      }
      if (this.playerOnFloor) {
        if (this.keyStates['Space']) {
          this.playerVelocity.y = 6
        }
      }
    },
    teleportPlayerIfOob() {
      if (this.camera.position.y <= -15) {
        this.playerCollider.start.set(
          this.cameraOriginal[0],
          this.cameraOriginal[1],
          this.cameraOriginal[2]
        )
        this.playerCollider.end.set(
          this.cameraOriginal[0],
          this.cameraOriginal[1] + 1,
          this.cameraOriginal[2]
        )
        this.playerCollider.radius = 0.35
        this.camera.position.copy(this.playerCollider.end)
      }
      },
    stopAndReleaseAnimations() {
      if (this.andh && this.andh.length > 0) {
    
    this.theMixer.stopAllAction();
    this.theMixer.uncacheAction(this.action);
    // 停止动画
    this.andh.forEach((animation) => {
      animation.stop();
    });

    // 清空动画数组
    this.andh = [];

    // 释放资源
    this.renderer.dispose(); // 如果使用WebGLRenderer，可以释放Renderer的资源
    this.objects.forEach((object) => {
      if (object.geometry) {
        object.geometry.dispose();
      }
      if (object.material) {
        object.material.dispose();
      }
    });
    this.objects = [];

    // 其他可能的资源释放逻辑

    console.log('当前播放的动画已停止并释放资源');
  }
}
    }
};